<template>
  <div class="my-form">
    <div class="header">
      <slot name="header"></slot>
    </div>
    <el-form :label-width="labelWidth">
      <el-row>
        <template v-for="item in formItems" :key="item.label">
          <el-col v-bind="colLayout">
            <el-form-item
              v-if="!item.isHidden"
              :label="item.label"
              :rules="item.rules"
              :style="itemStyle"
            >
              <template
                v-if="item.type === 'input' || item.type === 'password'"
              >
                <!-- v-model="formData[`${item.field}`]" -->
                <el-input
                  :model-value="props.modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item.field)"
                  :placeholder="item.placeholder"
                  v-bind="item.otherOptions"
                  :show-password="item.type === 'password'"
                ></el-input>
              </template>
              <template v-else-if="item.type === 'select'">
                <el-select
                  :model-value="props.modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item.field)"
                  :placeholder="item.placeholder"
                  style="width: 100%"
                  v-bind="item.otherOptions"
                >
                  <el-option
                    v-for="option in item.options"
                    :key="option.value"
                    :value="option.value"
                    >{{ option.title }}</el-option
                  >
                </el-select>
              </template>
              <template v-else-if="item.type === 'datepicker'">
                <el-date-picker
                  v-bind="item.otherOptions"
                  :model-value="props.modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item.field)"
                  style="width: 100%"
                >
                </el-date-picker>
              </template>
              <template v-else-if="item.type === 'upload'">
                <el-upload
                  :limit="1"
                  action="#"
                  list-type="picture"
                  :auto-upload="false"
                  accept="image/png,image/gif,image/jpg,image/jpeg"
                  :on-change="imgSaveToUrl"
                  :show-file-list="false"
                  ref="frontUpload"
                >
                  <img
                    class="icon-img"
                    v-if="imageFrontUrl"
                    :src="imageFrontUrl"
                  />
                  <el-icon v-else class="el-icon-plus"></el-icon>
                </el-upload>
              </template>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </el-form>
    <div class="footer">
      <slot name="footer"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { PropType, ref, watch } from 'vue'
import type { IFormItem } from '../types'
import { updateItemFile } from '../../../service/main/system/system'
const props = defineProps({
  formItems: {
    type: Array as PropType<IFormItem[]>,
    // type: IFormItem[],
    //基本类型直接写 数组对象箭头函数
    default: () => []
  },
  labelWidth: {
    type: String,
    default: '100px'
  },
  itemStyle: {
    type: Object,
    default: () => ({ padding: '10px 40px' })
  },
  colLayout: {
    type: Object,
    default: () => ({
      xl: 6,
      lg: 8,
      md: 12,
      sm: 24,
      xs: 24
    })
  },
  //v-model:modelValue="formData" modelValue is default Value
  modelValue: {
    type: Object,
    required: true
  }
})
const emit = defineEmits([`update:modelValue`])
//使用reactive传入props 时候代表该方法在set时候没用调用 仍然直接更改传入的reactive 应使用watch 一个新对象改变
// const formData = computed({
//   get: () => props.modelValue,
//   set: (newValue) => {
//     console.log(1111111)
//     emit(`update:modelValue`, newValue)
//   }
// })

//无法刷新的原因：ref+浅拷贝字符串类型=>值的直接复制 新的对象 无法侦测到原先数据的变化
// const formData = ref({ ...props.modelValue })
// const formData = computed(() => ({ ...props.modelValue }))

//computed穿入一个getter函数=>不可变ref 或者一个对象含有getset方法 get:()set:() 可变ref
//watch 直接监听一个ref 或者监听一个getter(回调)
// watch(
//   () => props.modelValue,
//   (newValue) => {
//     formData.value = { ...newValue }
//   }
// )
const handleValueChange = (value: any, field: string) => {
  emit('update:modelValue', { ...props.modelValue, [field]: value })
}
const param = new FormData()
const frontUpload = ref(null)
const imageFrontUrl = ref('')
const imgSaveToUrl = (file: any) => {
  param.append(`picture`, file.raw)

  emit('update:modelValue', { ...props.modelValue, avatar: param })
  imageFrontUrl.value = URL.createObjectURL(file.raw)
  const fileSize = file.size
  const fileType = file.raw.type
  if (!fileSize) {
    // 是否为空
    ElMessage({
      type: 'error',
      showClose: true,
      message: '无效的文件，请重新选择！'
    })
    return
  }
  if (fileSize / 1024 / 1024 > 10) {
    // 图片大小
    ElMessage({
      type: 'error',
      showClose: true,
      message: '请上传小于10M的图片！'
    })
    return
  }
  if (fileType.indexOf('image') === -1) {
    // 如果不是图片格式
    ElMessage({
      type: 'error',
      showClose: true,
      message: '不是有效的图片文件，或格式不支持，请重新选择!'
    })
    return
  }
}
// watch(
//   formData,
//   (newValue) => {
//     console.log(111)

//     emit(`update:modelValue`, newValue)
//   },
//   { deep: true }
// )
</script>

<style scoped lang="less">
.my-form {
  padding-top: 22px;
}
.icon-img {
  width: 50px;
}
</style>
